﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using System.Data;
using InTheHand.Net.Sockets;
using InTheHand.Net.Bluetooth;
using InTheHand.Net;
using System.IO;
using System.Collections;

namespace BluetoothTransmitter
{
    public class Transmitter
    {
        int STATIC_KOEFF = 5;
        int change = 0;
        string str;
        bool _shouldStop = false;
        byte[] Buffer = new byte[300];
        Stream stream = null;
        Random r = new Random();
        byte configRequest = 9;
        byte dataRequest = 8;
        int Read = 0;
        Guid serviceName = new Guid("{00001402-0000-1000-8000-00805F9B34FB}");
        BluetoothDeviceInfo[] deviceArray;
        InTheHand.Net.Sockets.BluetoothClient _bc = new InTheHand.Net.Sockets.BluetoothClient();
        BluetoothListener lsnr;

        public void connectionWait()
        {
                lsnr = new BluetoothListener(serviceName);
                lsnr.Start();
                _bc = lsnr.AcceptBluetoothClient();
                stream = _bc.GetStream();
        }

        /// <summary>
        /// Возвращает true, если получен запрос от сервера
        /// </summary>
        public string requestListner()
        {

            if (stream == null)
            {

                return null;
            }
            InTheHand.Net.Sockets.BluetoothListener btListener = new BluetoothListener(serviceName);
            byte[] msgSend = { 0 };
                try
                {
                    stream.ReadTimeout = 10;
                    Read = stream.Read(Buffer, 0, 44);
                    if (Read.Equals(dataRequest))
                    {
                        return "dataReqest";
                    }
                    else
                    {
                        if(Read.Equals(configRequest))
                        {
                            return "configReqest";
                        }
                    }
                    return null;
                }
                catch (Exception exeption)
                {
                    return null;
                }
            
        }
        /// <summary>
        /// Посылает клиенту положительный ответ
        /// </summary>
        public void okAnswer()
        {
            Byte[] answer = {1};
            stream.Write(answer, 0, answer.Length);
        }

        /// <summary>
        /// Получает от клиента тип конфигурации, который нужно установить
        /// </summary>
        public int resiveConfigType()
        {
            int configType=-1;
            try
            {
                stream.ReadTimeout = 100;
                configType = stream.Read(Buffer, 0, 44);
                return configType;
            }
            catch (Exception exeption)
            {
                return -2;
            }
        }

        /// <summary>
        /// Посылает в поток два байта, отражающие количество накопленных данных (число рр интервалов)
        /// </summary>
        public void radio(Int16 currentPosition)
        {
            bool islittleEndian = BitConverter.IsLittleEndian;
            Byte[] send= {0, 0};
            Byte[] dataLength = BitConverter.GetBytes(currentPosition);
                if (islittleEndian)
                {
                    send[0] = dataLength[1];
                    send[1] = dataLength[0];
                }
                else
                {
                    send[0] = dataLength[0];
                    send[1] = dataLength[1];
                }
                stream.Write(send, 0, 2);
        }

        /// <summary>
        /// Возвращает поток при успешном соединении с сервером
        /// </summary>
        public Stream connect(String name)
        {
            for(int i=0; i<deviceArray.GetLength(1); i++)
            {
                if (deviceArray[i].DeviceName == name)
                {
                    _bc.Connect(new BluetoothEndPoint(deviceArray[i].DeviceAddress, serviceName));
                    stream = _bc.GetStream();
                    return stream;
                }
            }
            return null;
        }

        /// <summary>
        /// Возвращает массив данных обнаруженных девайсов
        /// </summary>
        public void discovery()
        {
            deviceArray = _bc.DiscoverDevices(100, true, false, true);
        }


        /// <summary>
        /// Посылает серверу массив байтов
        /// </summary>
        public void sendData(Int16[] arrayOfInterval, Int16 currentPositionOfArray)
        {
            Byte[] data = getByteArray(arrayOfInterval, currentPositionOfArray);
            stream.Write(data, 0, data.Length);
        }

        /// <summary>
        /// Собирает массив байтов для отправлния на смартфон
        /// </summary>
        private Byte[] getByteArray(Int16[] arrayOfInterval, Int16 currentPositionFromArray)
        {
            bool islittleEndian = BitConverter.IsLittleEndian;
            bool notComplited = true;
            int currentPosition = 0;
            int bytePosition = 0;
            int length = currentPositionFromArray;
            Byte[] arrayToSend = new Byte[1];
            while (notComplited)
            {
                Byte[] bytes = BitConverter.GetBytes(arrayOfInterval[currentPosition]);
                if (islittleEndian)
                {
                    arrayToSend[bytePosition]= bytes[1];
                    IncreaseLength(ref arrayToSend, 1);
                    bytePosition++;
                    arrayToSend[bytePosition] = bytes[0];
                    IncreaseLength(ref arrayToSend, 1);
                    bytePosition++;
                }
                else
                {
                    arrayToSend[bytePosition] = bytes[0];
                    IncreaseLength(ref arrayToSend, 1);
                    bytePosition++;
                    arrayToSend[bytePosition] = bytes[1];
                    IncreaseLength(ref arrayToSend, 1);
                    bytePosition++;
                }
                currentPosition++;

                if (currentPosition == length)
                {
                    for (int i = 0; i < length; i++)
                    {
                        arrayOfInterval[i] = 0;
                    }
                    currentPositionFromArray = 0;
                    currentPosition = 0;
                    notComplited = false;
                    return arrayToSend;
                }
            }
            return arrayToSend;
        }
        private static void IncreaseLength(ref Byte[] arr, int delta)
        {
            Byte[] tmp = new Byte[arr.Length + delta];
            Array.Copy(arr, 0, tmp, 0, arr.Length);
            arr = tmp;
        }
    }
}
